package front;

import controller.CitationController;
import controller.TextController;
import entity.db.CitationTextDB;
import entity.db.ReferencestableDB;
import entity.text.ChapterEntity;
import entity.text.Paper;
import entity.text.PaperEntity;
import operation.TextOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.similarity.JaccardSimilarity;
import util.CollectionUtils;
import util.JDBCUtil;
import util.JaccardTextSimilarity;
import util.PaperEntityUtil;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;

/**
 * @author ：hzs
 * @date ：Created in 2020/12/4 16:32
 * @description：
 * @modified By：
 * @version: $
 */
public class CitationFront {

    private CitationController citationController = new CitationController();

    private TextController textController = new TextController();

    private static String xmlFilePath = "D:\\paper_database\\ai\\%s.xml";

    private static String pdfFilePath = "G:\\pdfpaper\\ai\\%s.pdf";

    private static String txtFilePath = "G:\\AITXT\\1-s2.0-%s-main.txt";

    private Map<String, File> idFileMap = new HashMap<>();

    /**
     * 看看引用链有多少数据
     */
    public void watchCitationChain() {
        List<List<Object>> argumentChainCitationAdjacency = citationController.getArgumentChainCitationAdjacency();
        argumentChainCitationAdjacency.forEach((a) -> {
            System.out.println(String.format("%d引用了%d", a.get(0), a.get(1)));
        });
    }

    /**
     * 确认文件是否存在
     */
    @Deprecated
    public void confirmFile() throws Exception{
        List<List<Object>> argumentChainCitationAdjacency = citationController.getArgumentChainCitationAdjacency();
        List<String> ids = new ArrayList<>();
        for (List<Object> arcs : argumentChainCitationAdjacency) {
            ids.add(String.valueOf(arcs.get(0)));
        }
        argumentChainCitationAdjacency.forEach(a -> ids.add(String.valueOf(a.get(0))));
        Map<String, String> idCodeMap = citationController.getFileNameByIDs(ids);
        this.idFileMap = new HashMap<>(idCodeMap.size());
        for(Map.Entry<String, String> map : idCodeMap.entrySet()) {
            String id = map.getKey();
            String fileCode = map.getValue();
            // txt
            File file = new File(txtFilePath + fileCode + "-main.txt");
            if (file.exists()) {
                idFileMap.put(id, file);
            }
            // xml
            file = new File(xmlFilePath + fileCode + ".xml");
            if (file.exists()) {
                idFileMap.put(id, file);
            } else {
                String format = String.format("缺失文章%s的文件%s", map.getKey(), map.getValue());
                throw new Exception(format);
            }
        }
    }

    /**
     * 根据ID读文件，返回章节结构
     * @param id
     */
    public PaperEntity readPaperById(String id) throws Exception{
        List<String> ids = new ArrayList<>();
        ids.add(id);
        String fileCode = citationController.getFileNameByIDs(ids).get(id);
        PaperEntity paperEntity = null;
        File file = new File(String.format(txtFilePath, fileCode));
        if (!file.exists()) {
            file = new File(String.format(xmlFilePath, fileCode));
        }
        if (file.exists()) {
            paperEntity = citationController.readPaperFromFile(file);
        }
        if (paperEntity == null) {
            file = new File(String.format(pdfFilePath, fileCode));
            if (!file.exists()) {
//                System.out.println(String.format("文章%s的文件不存在！文件码是%s", id, fileCode));
//                System.out.println(fileCode);
                return null;
            }
            return citationController.readPaperFromFile(file);
        }
        return paperEntity;
    }

    public void getMissingPaperEntity() {
        Map<String, List<String>> citationText = citationController.getCitationText();
        List<ReferencestableDB> citationAdjacencyBycommunityid = citationController.getCitationAdjacencyBycommunityid(20);
        Set<String> result = new HashSet<>();
        for (ReferencestableDB adjacency : citationAdjacencyBycommunityid) {
            String source = adjacency.getPaperid();
            String target = adjacency.getReferedid();

            String key = source + "," + target;
            if (!citationText.keySet().contains(key)) {
                result.add(source);
                result.add(target);
            }
        }
        result.forEach(System.out::println);
    }

    /**
     * 一键生成知识流
     * 过时，数据库结构改了
     */
    @Deprecated
    public void generateKnowledgeFlow() throws Exception {
//        confirmFile();
        // 下面的代码考虑下沉到service层
//        List<List<Object>> argumentChainCitationAdjacency = citationController.getArgumentChainCitationAdjacency();
        Map<String, List<String>> citationText = citationController.getCitationText();

        int i = 0;
        List<CitationTextDB> citationTextDBList = new ArrayList<>();
        List<ReferencestableDB> citationAdjacencyBycommunityid = citationController.getCitationAdjacencyBycommunityid(20);
        for (ReferencestableDB adjacency : citationAdjacencyBycommunityid) {
            String source = adjacency.getPaperid();
            String target = adjacency.getReferedid();
            String citationIndex = adjacency.getLabel();

            String key = source + "," + target;
            if (citationText.keySet().contains(key)) {
                continue;
            }

            boolean available = true;
            PaperEntity sourcePaper = readPaperById(source);
            if (sourcePaper == null) {
                available = false;
                System.out.println(String.format("文章%s未找到", source));
            }
            PaperEntity targetPaper = readPaperById(target);
            if (!validatePaperEntity(targetPaper)) {
                available = false;
                System.out.println(String.format("文章%s未找到", target));
            }

//            available = false;
            List<String> citations = null;
            if (available) {
                citations = new ArrayList<>();
                try {
                    citations = citationController.extractorCitation(sourcePaper, citationIndex);
//                System.out.println(String.format("%d引用%d完成", source, target));
                } catch (Exception e) {
                    available = false;
                    e.printStackTrace();
                }
            }

//            available = false;
            if (available) {
//                double similarity = JaccardTextSimilarity.getSimilarity(PaperEntityUtil.getFullTextFromPaperEntity(sourcePaper)
//                        , PaperEntityUtil.getFullTextFromPaperEntity(targetPaper));
                double similarity = 0.0;
                List<ChapterEntity> targetPaperChapterEntities = targetPaper.getChapterEntities();
                for (String citation : citations) {
                    if (citation.length() > 100) {
                        continue;
                    }
                    List<String> nounPhraseFromSentence = textController.getNounPhraseFromSentence(citation);
                    for (String s : nounPhraseFromSentence) {
                        int count = 0;
                        for (ChapterEntity targetPaperChapterEntity : targetPaperChapterEntities) {
                            String content = targetPaperChapterEntity.getContent();
                            //TODO：结合词频
                            if (containNouns(content, s)) {
                                count++;
                            }
                        }
                        double value = 1.0 * count / targetPaperChapterEntities.size();
                        CitationTextDB citationTextDB = new CitationTextDB();
                        citationTextDB.setSource(Integer.valueOf(source));
                        citationTextDB.setTarget(Integer.valueOf(target));
                        citationTextDB.setCitationIndex(citationIndex);
                        if (citation.length() > 4999) {
                            citationTextDB.setCitation("抽取的引文太长");
                        } else {
                            citationTextDB.setCitation(citation
                                    .replace("\"", "\\\"")
                                    .replace("\'", "\\\'"));
                        }
                        citationTextDB.setSimilarity(String.valueOf(similarity));
//                        citationTextDB.setDistribution(String.valueOf(value));
//                        citationTextDB.setNounPhrase(s);
                        citationTextDBList.add(citationTextDB);
//                    System.out.println(source + "\t" + target + "\t" + citationIndex + "\t" + s + "\t" + value);
                        // fixme 违规操作
//                        Connection connection = JDBCUtil.getConnection();
//                        String sql = "INSERT INTO `citation_text` (source, target, citation_index,similarity, distribution, noun_phrase) VALUE(" +
//                                source + "," + target + ",'" + citationIndex + "','"+ similarity + "','" + value + "','" + s + "')";
//                        Statement statement = connection.createStatement();
//                        boolean execute = statement.execute(sql);
//                        connection.close();
//                    maxValue = Math.max(maxValue, value);
                    }
                }
                // 写入数据库
                if (citationTextDBList.size() > 100) {
                    citationController.insertCitationText(citationTextDBList);
                    citationTextDBList = new ArrayList<>();
                }
            }
        }
        // 写入数据库
        if (!CollectionUtils.isEmpty(citationTextDBList)) {
            citationController.insertCitationText(citationTextDBList);
        }

    }

    boolean validatePaperEntity(PaperEntity paperEntity) {
        List<ChapterEntity> sourcePaperChapterEntities = null;
        if (paperEntity == null) {
            return false;
        } else {
            sourcePaperChapterEntities = paperEntity.getChapterEntities();
            if (CollectionUtils.isEmpty(sourcePaperChapterEntities)) {
                return false;
            }
        }
        return true;
    }

    boolean containNouns(String content, String nouns) {
        String[] split = nouns.split(" ");
        int length = split.length;
        int count = 0;
        for (String s : split) {
            if (content.contains(s)) {
                count++;
            }
//            if (content.contains(" " + s + "")
//                    || content.contains(" " + s + "\n")
//                    || content.contains("\n" + s + " ")
//                    || content.startsWith(s + " ")
//                    || content.endsWith(" " + s)) {
//                count++;
//            }
        }
        if (1.0*count/length > 0.5) {
            return true;
        }
        return false;
    }


}
